package com.gjw.blog.service.impl;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gjw.blog.entity.Post;
import com.gjw.blog.mapper.PostMapper;
import com.gjw.blog.service.PostService;
import com.gjw.blog.utils.RedisUtil;
import com.gjw.blog.vo.PostVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author gjw199513
 * @since 2019-11-06
 */
@Service
public class PostServiceImpl extends ServiceImpl<PostMapper, Post> implements PostService {

    @Autowired
    RedisUtil redisUtil;

    @Autowired
    PostMapper postMapper;

    @Override

    public void initIndexWeekRank() {
        List<Post> last7DayPosts = this.list(new QueryWrapper<Post>().
                ge("created", DateUtil.offsetDay(new Date(), -7).toJdkDate()).
                select("id,title,user_id,comment_count,view_count,created"));

        for (Post post : last7DayPosts) {
            String key = "day_rank:" + DateUtil.format(post.getCreated(), DatePattern.PURE_DATE_PATTERN);

            //  设置有效期
            long between = DateUtil.between(new Date(), post.getCreated(), DateUnit.DAY);
            long expireTime = (7 - between) * 24 * 60 * 60;
            // 缓存文章到set中，评论数量作为排行标准
            redisUtil.zSet(key, post.getId(), post.getCommentCount());
            // 设置有效期
            redisUtil.expire(key, expireTime);
            // 缓存文章基本信息（hash结构）
            this.hashCachePostIdAndTitle(post);

        }
        // 七天阅读数相加
        this.zUnionAndStoreLast7DaysForLastWeekRand();
    }

    /**
     * hash结构缓存文章标题和id
     *
     * @param post
     */
    private void hashCachePostIdAndTitle(Post post) {
        boolean isExist = redisUtil.hasKey("rank_post_" + post.getId());
        if (!isExist) {
            long between = DateUtil.between(new Date(), post.getCreated(), DateUnit.DAY);
            long expireTime = (7 - between) * 24 * 60 * 60;

            // 缓存文章基本信息（hash结构）
            redisUtil.hset("rank_post_" + post.getId(), "post:id", post.getId(), expireTime);
            redisUtil.hset("rank_post_" + post.getId(), "post:title", post.getTitle(), expireTime);
//            redisUtil.hset("rank_post_" + post.getId(), "post:comment_count", post.getCommentCount(), expireTime);

        }
    }

    /**
     * 把最近7天的文章评论数量统计一下
     * 用于首页的七天评论排行榜
     */
    private void zUnionAndStoreLast7DaysForLastWeekRand() {
        String prefix = "day_rank:";

        List<String> keys = new ArrayList<>();
        String key = prefix + DateUtil.format(new Date(), DatePattern.PURE_DATE_PATTERN);
        for (int i = -7; i < 0; i++) {
            Date date = DateUtil.offsetDay(new Date(), i).toJdkDate();
            keys.add(prefix + DateUtil.format(date, DatePattern.PURE_DATE_PATTERN));
        }

        redisUtil.zUnionAndStore(key, keys, "last_week_rank");
    }

    @Override
    @Cacheable(cacheNames = "cache_post", key = "'page_' + #page.current + '_' + #page.size " +
            "+ '_query_' +#categoryId + '_' + #order")
    public IPage paging(Page page, Long categoryId, String order) {
        QueryWrapper<Post> wrapper = new QueryWrapper<Post>().
                eq(categoryId != 0, "category_id", categoryId)
                .orderByDesc(order);

        IPage<PostVo> pageData = postMapper.selectPosts(page, wrapper);
        return pageData;

    }
}
